package com.moutai.wmo.core.security.config;

import com.moutai.wmo.core.security.service.LoginUserDetailService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Slf4j
@Configuration
@EnableWebSecurity //开启spring security，之后会默认注册大量过滤器
public class SecurityConfig {

    @Resource
    private LoginUserDetailService loginUserDetailService;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        log.info("开始配置HttpSecurity ...");
        http  //HttpSecurity的配置
                .cors(Customizer.withDefaults()) //跨站资源共享(跨域访问)
                .csrf(AbstractHttpConfigurer::disable) //禁用csrf保护，前后端分离不需要
                /* 验证策略 */
                .authorizeHttpRequests(auth -> auth
                        // 无需验证，放行
                        .requestMatchers("/login").permitAll() //登录接口
                        .requestMatchers("/register").permitAll() //注册接口
                        // 其它请求均需鉴权认证
                        .anyRequest().authenticated()
                )
                /* 表单登录 */
                .formLogin(form -> form
                        .loginProcessingUrl("/login")
                        // 登录成功处理器
                        .successHandler((request, response, authentication) -> {
                            response.setContentType("text/html;charset=UTF-8");
                            response.getWriter().write("login OK");
                            log.info("Principal Credentials Authorities");
                            System.out.println(authentication.getPrincipal());
                            System.out.println(authentication.getCredentials());
                            System.out.println(authentication.getAuthorities());
                        })
                        // 登录失败处理器
                        .failureHandler((request, response, exception) -> {
                            response.setContentType("text/html;charset=UTF-8");
                            response.getWriter().write("login error");
                            log.error(exception.getMessage(), exception);
                        })
                )
                /*  自定义 AuthenticationProvider */
                .authenticationProvider(authenticationProvider());
        return http.build();
    }

    @Bean //将PasswordEncoder注册成Bean，PasswordEncoder 的实现类为 BCryptPasswordEncoder
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean //将AuthenticationProvider注册成Bean，AuthenticationProvider使用了PasswordEncoder和UserDetailsService
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(passwordEncoder()); //密码编码器
        provider.setUserDetailsService(this.loginUserDetailService); //UserDetailsService
        return provider;
    }

}
